package com.rentong.wx.cust.service.impl;

import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.rentong.basic.BusinessException;
import com.rentong.common.DateUtils;
import com.rentong.wx.cust.dao.*;
import com.rentong.wx.cust.domain.*;
import com.rentong.wx.cust.service.CustOrderPayService;
import com.rentong.wx.utils.PayStateEnum;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;

@Service
public class CustOrderPayServiceImpl implements CustOrderPayService {

    @Resource
    private CustOrderPayDao custOrderPayDao;

    @Resource
    private CustServiceOrderDao custServiceOrderDao;

    @Resource
    private CustServiceOrderChefDao custServiceOrderChefDao;

    @Resource
    private CustServiceOrderAdvDao custServiceOrderAdvDao;

    @Resource
    private WxPayService wxPayService;

    @Resource
    private WxCustUserMapper wxCustUserMapper;

    @Resource
    private CustFlowDao custFlowDao;

    @Resource
    private CustFlowTypeDao custFlowTypeDao;

    @Resource
    private CustCanyinquanDao custCanyinquanDao;

    @Resource
    private CustGetCanyinquanPhoneDao custGetCanyinquanPhoneDao;

    @Resource
    private CustGetServiceOrderPhoneDao custGetServiceOrderPhoneDao;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void payNotify(String xmlResult) throws Exception {
        if (StringUtils.isBlank(xmlResult)) {
            throw new WxPayException("返回数据为空");
        }

        WxPayOrderNotifyResult result = wxPayService.parseOrderNotifyResult(xmlResult);
        // 结果正确
        Long payId = Long.parseLong(result.getOutTradeNo());

        //判断订单是否已支付
        CustOrderPayEntity custOrderPayEntity = custOrderPayDao.selectByPrimaryKey(payId);
        int payState = custOrderPayEntity.getPayState();
        if (payState != PayStateEnum.PAYING.getState()) {
            //非支付中状态，直接返回
            return;
        }

        //查询该订单是否为订单
        Long order = 0L;
        CustServiceOrderEntity wcsod = custServiceOrderDao.getOrderInfoById(custOrderPayEntity.getOrderId(), custOrderPayEntity.getCustId());
        CustServiceOrderAdvEntity wcsoad = new CustServiceOrderAdvEntity();
        if (wcsod == null) {
            wcsoad = custServiceOrderAdvDao.selectByPrimaryKey(custOrderPayEntity.getOrderId());
            if (wcsoad == null) {
                throw new WxPayException("无此订单！");
            }else {
                order = wcsoad.getServiceOrderId();
            }
        }else {
            order = wcsod.getServiceOrderId();
        }

        String resultCode = result.getReturnCode();
        String returnCode = result.getResultCode();
        CustOrderPayEntity tmpPay = new CustOrderPayEntity();
        tmpPay.setPayId(payId);

        if ("SUCCESS".equals(returnCode) && "SUCCESS".equals(resultCode)) {
            tmpPay.setPayAmount(new BigDecimal(result.getTotalFee()));
            tmpPay.setTradeNo(result.getTransactionId());
            tmpPay.setPayTime(DateUtils.getDate(result.getTimeEnd(), "yyyyMMddHHmmss"));
            tmpPay.setPayState(PayStateEnum.PAY_SUCCESS.getState());

        } else {
            custServiceOrderDao.deleteByPrimaryKey(custOrderPayEntity.getOrderId());
            custServiceOrderAdvDao.deleteByPrimaryKey(custOrderPayEntity.getOrderId());

            tmpPay.setPayState(PayStateEnum.PAY_FAIL.getState());
            tmpPay.setFailCode(result.getErrCode());
            tmpPay.setFailDesc(result.getErrCodeDes());
            custOrderPayDao.updateByPrimaryKeySelective(tmpPay);
            return;
        }

        int updNum = custOrderPayDao.updateByPrimaryKeySelective(tmpPay);
        if (updNum > 0) {
            //支付回调，处理业务（微信、支付宝）
            alipayAndweixinNotify(order);
        }
    }

    //支付回调，处理业务（微信、支付宝）
    public void alipayAndweixinNotify(Long orderNo) {

        //判断下是什么类型的订单
        if (orderNo.toString().length() == 19) {
            //长度为19位，下单的是普通订单
            CustServiceOrderEntity csoo = custServiceOrderDao.selectByPrimaryKey(orderNo);

            //修改订单状态，订单表的其他值
            CustServiceOrderEntity cso = new CustServiceOrderEntity();
            cso.setServiceOrderId(csoo.getServiceOrderId());
            cso.setTrueAmount(csoo.getPayAmount());
            cso.setPayTime(new Date());

            if (csoo.getOrderType() == 3 || csoo.getOrderType() == 5) {
                //单点师傅时，状态默认为待接单
                cso.setOrderState(2);

                //录入师傅接单的表（有可能是主动抢单，也有可能是被动指定的。师傅端，查询有哪些订单，以这张表为主表）
                CustServiceOrderChefEntity csoc = new CustServiceOrderChefEntity();
                csoc.setServiceOrderId(csoo.getServiceOrderId());
                csoc.setChefId(csoo.getChefId());
                csoc.setServiceOrderChefState(2);
                cso.setUpdateTime(new Date());
                csoc.setAddTime(new Date());
                custServiceOrderChefDao.insertSelective(csoc);

            } else if (csoo.getOrderType() == 4) {
                cso.setOrderState(1);

            } else {
                //到店代厨·商家报价、到店代厨·师傅报价，状态默认为待服务
                cso.setOrderState(3); //待服务
                CustServiceOrderChefEntity orderChefEntity = custServiceOrderChefDao.getByStat(csoo.getServiceOrderId());
                cso.setChefId(orderChefEntity.getChefId());
                //把其他师傅改成被拒绝
                custServiceOrderChefDao.updateStatByOrderId(csoo.getServiceOrderId());

                CustFlowEntity custFlowEntity = new CustFlowEntity();
                custFlowEntity.setCustId(csoo.getPayCustId());
                custFlowEntity.setType(2);
                custFlowEntity.setFlowTypeName("余额消费");
                custFlowEntity.setFlowTypeId(4L);
                custFlowEntity.setFee(csoo.getPayAmount());
                custFlowEntity.setServiceOrderId(csoo.getServiceOrderId());
                custFlowEntity.setAddTime(new Date());
                custFlowDao.insert(custFlowEntity);
            }

            custServiceOrderDao.updateByPrimaryKeySelective(cso);

        } else if (orderNo.toString().length() == 18) {

            System.out.println("==================123==============");
            //其他订单（电话、充值、帮上推等）
            CustServiceOrderAdvEntity csoa = custServiceOrderAdvDao.selectByPrimaryKey(orderNo);

            //修改订单状态，订单表的其他值
            CustServiceOrderAdvEntity cs = new CustServiceOrderAdvEntity();
            cs.setServiceOrderId(orderNo);
            cs.setOrderState(3);
            custServiceOrderAdvDao.updateByPrimaryKeySelective(cs);

            if (csoa.getOrderType() == 1 || csoa.getOrderType() == 2) {
                // 1：用户充值；2：厨师充值；
                WxCustUser wxCustUser = wxCustUserMapper.selectByPrimaryKey(csoa.getCustId());

                //修改用户表余额
                WxCustUser wcu = new WxCustUser();
                wcu.setCustId(wxCustUser.getCustId());
                wcu.setBalanceAmount(wxCustUser.getBalanceAmount().add(csoa.getGetAmount()));
                wcu.setUpdateTime(new Date());
                wxCustUserMapper.updateByPrimaryKeySelective(wcu);

                //修改流水表
                CustFlowTypeEntity custFlowTypeEntity = custFlowTypeDao.selectByPrimaryKey(1L);
                CustFlowEntity cf = new CustFlowEntity();
                cf.setCustId(csoa.getCustId());
                cf.setType(custFlowTypeEntity.getType());
                cf.setFlowTypeId(custFlowTypeEntity.getFlowTypeId());
                cf.setFlowTypeName(custFlowTypeEntity.getFlowTypeName());
                cf.setFee(csoa.getGetAmount());
                cf.setFeeBefore(wxCustUser.getBalanceAmount());
                cf.setFeeAfter(wcu.getBalanceAmount());
                cf.setServiceOrderId(orderNo);
                cf.setAddTime(new Date());
                custFlowDao.insertSelective(cf);

            } else if (csoa.getOrderType() == 3 || csoa.getOrderType() == 4) {
                // 3：用户购买餐饮圈电话；4：厨师购买餐饮圈电话；
                CustGetCanyinquanPhoneEntity cgcp = new CustGetCanyinquanPhoneEntity();
                cgcp.setCanyinquanId(csoa.getRelationId());
                cgcp.setCustId(csoa.getCustId());
                cgcp.setCalledCustId(csoa.getNotifyRelationId());
                cgcp.setAddTime(new Date());
                custGetCanyinquanPhoneDao.insertSelective(cgcp);

            } else if (csoa.getOrderType() == 13 || csoa.getOrderType() == 14) {
                // 13：用户购买订单电话；14：厨师购买订单电话；
                CustGetServiceOrderPhoneEntity cgsop = new CustGetServiceOrderPhoneEntity();
                cgsop.setServiceOrderId(csoa.getServiceOrderId());
                cgsop.setCustType(csoa.getOrderType() == 13 ? 1 : 2);
                cgsop.setCustId(csoa.getCustId());
                cgsop.setCalledCustId(csoa.getNotifyRelationId());

                Date date = new Date(); // 当前日期和时间
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(date);
                calendar.add(Calendar.HOUR_OF_DAY, 24); // 增加24小时
                date = calendar.getTime();

                cgsop.setFailureTime(date);
                cgsop.setAddTime(new Date());
                custGetServiceOrderPhoneDao.insertSelective(cgsop);

            } else if (csoa.getOrderType() == 5 || csoa.getOrderType() == 6) {
                // 5：用户购买餐饮圈的帮上推；6：厨师购买餐饮圈的帮上推；
                CustCanyinquanEntity custCanyinquanEntity = custCanyinquanDao.selectByPrimaryKey(csoa.getNotifyRelationId());

                CustCanyinquanEntity cc = new CustCanyinquanEntity();
                cc.setCanyinquanId(custCanyinquanEntity.getCanyinquanId());

                if (custCanyinquanEntity.getToutiaoUtilTime() == null) {
                    //从来没买过。直接按当前日期，增加几个月
                    cc.setToutiaoUtilTime(com.rentong.wx.utils.DateUtils.getDateForDays(new Date(), Integer.parseInt(csoa.getGetAmount().toString())));
                } else if (custCanyinquanEntity.getToutiaoUtilTime().after(new Date())) {
                    cc.setToutiaoUtilTime(com.rentong.wx.utils.DateUtils.getDateForDays(custCanyinquanEntity.getToutiaoUtilTime(), Integer.parseInt(csoa.getGetAmount().toString())));
                } else {
                    cc.setToutiaoUtilTime(com.rentong.wx.utils.DateUtils.getDateForDays(new Date(), Integer.parseInt(csoa.getGetAmount().toString())));
                }
                cc.setUpdateTime(new Date());
                custCanyinquanDao.updateByPrimaryKeySelective(cc);

            } else if (csoa.getOrderType() == 7 || csoa.getOrderType() == 8) {
                // 7：用户购买厨师本身的帮上推；8：厨师购买厨师本身的帮上推；
                WxCustUser wxCustUser = wxCustUserMapper.selectByPrimaryKey(csoa.getNotifyRelationId());

                WxCustUser wc = new WxCustUser();
                wc.setCustId(wxCustUser.getCustId());
                if (wxCustUser.getBstUtilTime() == null) {
                    //从来没买过。直接按当前日期，增加几个月
                    wc.setBstUtilTime(com.rentong.wx.utils.DateUtils.getDateForDays(new Date(), Integer.parseInt(csoa.getGetAmount().toString())));
                } else if (wxCustUser.getBstUtilTime().after(new Date())) {
                    wc.setBstUtilTime(com.rentong.wx.utils.DateUtils.getDateForDays(wxCustUser.getBstUtilTime(), Integer.parseInt(csoa.getGetAmount().toString())));
                } else {
                    wc.setBstUtilTime(com.rentong.wx.utils.DateUtils.getDateForDays(new Date(), Integer.parseInt(csoa.getGetAmount().toString())));
                }
                wc.setUpdateTime(new Date());
                wxCustUserMapper.updateByPrimaryKeySelective(wc);

            } else if (csoa.getOrderType() == 9 || csoa.getOrderType() == 10) {
                // 9：用户购买单子的帮上推；10：厨师购买单子的帮上推；
                CustServiceOrderEntity custServiceOrderEntity = custServiceOrderDao.selectByPrimaryKey(csoa.getNotifyRelationId());

                CustServiceOrderEntity cso = new CustServiceOrderEntity();
                cso.setServiceOrderId(custServiceOrderEntity.getServiceOrderId());
                if (custServiceOrderEntity.getBstUtilTime() == null) {
                    //从来没买过。直接按当前日期，增加几个月
                    cso.setBstUtilTime(com.rentong.wx.utils.DateUtils.getDateForDays(new Date(), Integer.parseInt(csoa.getGetAmount().toString())));
                } else if (custServiceOrderEntity.getBstUtilTime().after(new Date())) {
                    cso.setBstUtilTime(com.rentong.wx.utils.DateUtils.getDateForDays(custServiceOrderEntity.getBstUtilTime(), Integer.parseInt(csoa.getGetAmount().toString())));
                } else {
                    cso.setBstUtilTime(com.rentong.wx.utils.DateUtils.getDateForDays(new Date(), Integer.parseInt(csoa.getGetAmount().toString())));
                }
                cso.setUpdateTime(new Date());
                custServiceOrderDao.updateByPrimaryKeySelective(cso);


            } else if (csoa.getOrderType() == 11 || csoa.getOrderType() == 12) {
                // 11：用户购买会员；12：厨师购买会员

                //修改用户表的会员
                WxCustUser wxCustUser = wxCustUserMapper.selectByPrimaryKey(csoa.getCustId());

                WxCustUser wcu = new WxCustUser();
                wcu.setCustId(wxCustUser.getCustId());

                if (wxCustUser.getHuiyuanTime() == null) {
                    //从来没买过会员。直接按当前日期，增加几个月
                    wcu.setHuiyuanTime(com.rentong.wx.utils.DateUtils.getDateForMonths(new Date(), Integer.parseInt(csoa.getGetAmount().toString())));

                } else if (wxCustUser.getHuiyuanTime().after(new Date())) {
                    //System.out.println("指定的日期比当前日期晚。");
                    wcu.setHuiyuanTime(com.rentong.wx.utils.DateUtils.getDateForMonths(wxCustUser.getHuiyuanTime(), Integer.parseInt(csoa.getGetAmount().toString())));

                } else {
                    //System.out.println("指定的日期不比当前日期晚。");
                    wcu.setHuiyuanTime(com.rentong.wx.utils.DateUtils.getDateForMonths(new Date(), Integer.parseInt(csoa.getGetAmount().toString())));

                }

                wcu.setHuiyuanNum(1);
                wcu.setUpdateTime(new Date());
                wxCustUserMapper.updateByPrimaryKeySelective(wcu);
            }

        } else {
            throw new BusinessException("支付异常！");
        }

    }


}